/**********************************************************************
 *
 * This code is developed for the course Informatica Industrial II
 * of Universidad Carlos III de Madrid  - 2012
 * Authors: Victor González-Pacheco, Alberto Valero-Gomez
 *
 * The code is licenced under the Common Creative License,
 * Attribution-ShareAlike 3.0
 *
 * You are free:
 *   - to Share - to copy, distribute and transmit the work
 *   - to Remix - to adapt the work
 *
 * Under the following conditions:
 *   - Attribution. You must attribute the work in the manner specified
 *     by the author or licensor (but not in any way that suggests that
 *     they endorse you or your use of the work).
 *   - Share Alike. If you alter, transform, or build upon this work,
 *     you may distribute the resulting work only under the same or
 *     similar license to this one.
 *
 * Any of the above conditions can be waived if you get permission
 * from the copyright holder.  Nothing in this license impairs or
 * restricts the author's moral rights.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.
 **********************************************************************/


#include <string>

#include <sys/socket.h>
#include <sstream>
#include <netdb.h>
#include <arpa/inet.h>
#include <strings.h>
#include <cstdio>
#include <cerrno>
#include <stdio.h>
#include <cstring>


#include "TCPSocketClient.h"


TCPSocket& TCPSocketClient::create(string ip, int port) throw (char const*)
{
    try{
        TCPSocket *sock = new TCPSocket(ip,port,"127.0.0.1",0);
        int fd = sock->getFileDescriptor(); //retrieve the file descriptor
        //connect the socket just created

        struct hostent *server;
        server = gethostbyname(ip.c_str());
        if (server == NULL) {
            throw("No such server name");
        }

        //Connect to the given server
        struct sockaddr_in serv_addr;
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        bcopy((char *)server->h_addr,
              (char *)&serv_addr.sin_addr.s_addr,
              server->h_length);
        serv_addr.sin_port = htons(port);
        if (::connect(fd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){
            stringstream strstr;
            strstr << "Error connecting to "
                   << inet_ntoa(serv_addr.sin_addr)
                   << ":"<<ntohs(serv_addr.sin_port)
                   << "\n"
                   << "socket file descriptor: "
                   << fd
                   << "\n"
                   << "Error number: "
                   << strerror(errno)
                   << " "
                   << errno
                      ;
            throw(strstr.str().c_str());
        }
        return *sock;
    }catch(char const* e){
        throw(e);
    }
}
